package com.adcc.ags.cgw.service;

import com.adcc.ags.cgw.entity.msg.*;
import com.adcc.ags.cgw.proxy.AMQSProxy;
import com.adcc.ags.cgw.proxy.MsgProxy;
import com.adcc.ags.cgw.proxy.UpLinkDispatchProxy;
import com.adcc.ags.cgw.proxy.UserProxy;
import com.adcc.ags.cgw.utils.Constant;
import com.adcc.utility.log.Log;
import com.google.common.base.Strings;

import java.util.List;

/**
 * 消息发送服务
 */
public class MsgSenderServiceImpl extends MsgSenderService {

    @Override
    protected void recordMsgSndCount(String userId,int type) {
        if(!Strings.isNullOrEmpty(userId) && UserProxy.getInstance().getUserInfoMap().containsKey(userId)){
            if(type == 0){
                long count = UserProxy.getInstance().getUserInfoMap().get(userId).getDownlink();
                UserProxy.getInstance().getUserInfoMap().get(userId).setDownlink(++count);
            }else{
                long count = UserProxy.getInstance().getUserInfoMap().get(userId).getUplink();
                UserProxy.getInstance().getUserInfoMap().get(userId).setUplink(++count);
            }
        }
    }

    @Override
    protected void sendDownlinkMsg(CGWMsg msg) {
        try{

            // 发送下行报文到用户
            try {
                UpLinkDispatchProxy.getInstance().sendDownlinkMsg(msg.getDestination().get(0).getQueue(), msg.getMsg().getContent(),msg.getType(), msg.getSender());
                Log.debug(MsgSenderService.class.getName(), "send downlink message to " + msg.getDestination().get(0) + "\r\n" + msg.getMsg().toString());
                recordMsgSndCount(msg.getDestination().get(0).getUserId(), 0);
            } catch (Exception ex) {
                Log.error(MsgSenderService.class.getName(), "send downlink message to " + msg.getDestination().get(0) + " failed\r\n" + msg.getMsg().toString(),ex);

                // MsgStore更新报文发送状态
                MsgProxy.getInstance().getMsgSaveActor().tell(new TrafficMsg(msg.getId(), Constant.ERROR_CODE_SND_DOWNLINK, msg.getReceiver()), this.getSelf());
            }
        }catch (Exception ex){
            Log.error(MsgSenderService.class.getName(),"sendDownlinkMsg() error",ex);
        }
    }

    @Override
    protected void sendUplinkMsg(CGWMsg msg) {
        try{
            boolean flag = false;

            // 发送上行报文到AMQS
            try {
                AMQSProxy.getInstance().sendUpLinkMsg(msg.getMsg().getContent());
                Log.debug(MsgSenderService.class.getName(), msg.getSender() + " send uplink message\r\n" + msg.getMsg().getContent().toString());
                recordMsgSndCount(msg.getSender(),1);
            }catch (Exception ex){
                Log.error(MsgSenderService.class.getName(),msg.getSender() + " send uplink message failed\r\n" + msg.getMsg().toString(),ex);
                MsgProxy.getInstance().getMsgSaveActor().tell(new TrafficMsg(msg.getId(),Constant.ERROR_CODE_SND_UPLINK,"1"),this.getSelf());
                flag = true;
            }

            // 转发上行报文到其他用户
            if(msg.getDestination() != null && msg.getDestination().size() > 0){
                StringBuilder sb = new StringBuilder();
                List<DestRoute> destList = msg.getDestination();
                for(DestRoute dr : destList){
                    try{
                        UpLinkDispatchProxy.getInstance().sendDownlinkMsg(dr.getQueue(), msg.getMsg().getContent(), MsgType.GROUND, msg.getSender());
                        Log.debug(MsgSenderService.class.getName(), "send ground message to " + dr.getUserId() + "\r\n" + msg.getMsg().toString());
                        recordMsgSndCount(dr.getUserId(),0);
                    }catch (Exception ex){
                        Log.error(MsgSenderService.class.getName(), "send ground message to " + dr.getUserId() + " failed\r\n" + msg.getMsg().toString(),ex);
                        sb.append(dr.getUserId()).append(" ");
                    }
                }

                // MsgStore更新报文发送状态
                if (!Strings.isNullOrEmpty(sb.toString().trim())) {
                    String strErrorCode = Constant.ERROR_CODE_SND_GROUND;
                    String strErrorUser = sb.toString().trim();

                    // 如果发送上行报文失败需要叠加上行报文发送错误代码和错误用户
                    if(flag){
                        strErrorCode = Constant.ERROR_CODE_SND_UPLINK + "," + Constant.ERROR_CODE_SND_GROUND;
                        strErrorUser = "1 " + strErrorUser;
                    }
                    MsgProxy.getInstance().getMsgSaveActor().tell(new TrafficMsg(msg.getId(),strErrorCode,strErrorUser),this.getSelf());
                }
            }
        }catch (Exception ex){
            Log.error(MsgSenderService.class.getName(),"sendUplinkMsg() error",ex);
        }
    }

    @Override
    protected void sendGroundMsg(CGWMsg msg) {
        try{

            // 发送地地报文到用户
            if(msg.getDestination() != null && msg.getDestination().size() > 0){
                StringBuilder sb = new StringBuilder();
                List<DestRoute> destList = msg.getDestination();
                for (DestRoute dr : destList) {
                    try {
                        UpLinkDispatchProxy.getInstance().sendDownlinkMsg(dr.getQueue(), msg.getMsg().getContent(),msg.getType(), msg.getSender());
                        Log.debug(MsgSenderService.class.getName(), "send ground message to " + dr.getUserId() + "\r\n" + msg.getMsg().toString());
                        recordMsgSndCount(dr.getUserId(), 0);
                    } catch (Exception ex) {
                        Log.error(MsgSenderService.class.getName(), "send ground message to " + dr.getUserId() + " failed\r\n" + msg.getMsg().toString(),ex);
                        sb.append(dr.getUserId()).append(" ");
                    }
                }

                // MsgStore更新报文发送状态
                if (!Strings.isNullOrEmpty(sb.toString().trim())) {
                    String strErrorUser = sb.toString().trim();
                    MsgProxy.getInstance().getMsgSaveActor().tell(new TrafficMsg(msg.getId(),Constant.ERROR_CODE_SND_GROUND,strErrorUser),this.getSelf());
                }
            }
        }catch (Exception ex){
            Log.error(MsgSenderService.class.getName(),"sendGroundMsg() error",ex);
        }
    }

    @Override
    public void onReceive(Object message) {
        super.onReceive(message);
        try{
            CGWMsg msg = (CGWMsg)message;
            if(msg != null){
                Log.debug(MsgSenderService.class.getName(),"MsgSender receive message\r\n" + msg.getMsg().toString());
                switch (msg.getType()){

                    // 发送下行报文
                    case DOWNLINK:
                        sendDownlinkMsg(msg);
                        break;

                    // 发送上行报文
                    case UPLINK:
                        sendUplinkMsg(msg);
                        break;

                    // 发送地地报文
                    case GROUND:
                        sendGroundMsg(msg);
                        break;
                    default:
                        unhandled(message);
                        break;
                }
            }else {
                unhandled(message);
            }
        }catch (Exception ex){
            Log.error(MsgSenderService.class.getName(),"onReceive() error",ex);
        }
    }
}
